package com.tomshushu.doc.freedoc.modular.directory.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tomshushu.doc.freedoc.core.exception.ServiceException;
import com.tomshushu.doc.freedoc.modular.directory.entity.DirectoryEntity;
import com.tomshushu.doc.freedoc.modular.directory.mapper.DirectoryMapper;
import com.tomshushu.doc.freedoc.modular.directory.model.param.AddDirectoryParam;
import com.tomshushu.doc.freedoc.modular.directory.model.param.DeleteDirectoryParam;
import com.tomshushu.doc.freedoc.modular.directory.model.param.GetChildDirectoryParam;
import com.tomshushu.doc.freedoc.modular.directory.model.param.ReNameParam;
import com.tomshushu.doc.freedoc.modular.directory.model.result.GetChildDirectoryListResult;
import com.tomshushu.doc.freedoc.modular.directory.service.DirectoryService;
import com.tomshushu.doc.freedoc.modular.doc.entity.DocEntity;
import com.tomshushu.doc.freedoc.modular.doc.service.DocService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: zhouhong
 * @date: 2025-06-11 12:20
 * @version: 1.0
 */

@Service
public class DirectoryServiceImpl  extends ServiceImpl<DirectoryMapper, DirectoryEntity> implements DirectoryService {

    @Resource
    private DocService docService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DirectoryEntity addDirectory(AddDirectoryParam param) {
        // 将dto转为实体
        DirectoryEntity directory = this.setAreaPids(param);
        BeanUtil.copyProperties(param, directory);
        directory.setCreateTime(new java.util.Date());
        this.save(directory);
        return directory;
    }

    @Override
    public void rename(@RequestBody ReNameParam param) {
        DirectoryEntity directory = this.getById(param.getId());
        if (ObjectUtil.isNotNull( directory)) {
            directory.setName(param.getName());
            this.updateById(directory);
        }
    }

    @Override
    public GetChildDirectoryListResult getChildDirectoryAndDocList(GetChildDirectoryParam param) {
        GetChildDirectoryListResult result = new GetChildDirectoryListResult();
        // 获取当前目录的子目录和文档
        List<GetChildDirectoryListResult.ChildDirectory> childDirectoryList = new ArrayList<>();
        List<GetChildDirectoryListResult.ChildDocument> childDocumentList = new ArrayList<>();
       this.list(new LambdaQueryWrapper<DirectoryEntity>()
                .eq(DirectoryEntity::getProjectId, param.getProjectId())
                .eq(DirectoryEntity::getTeamId, param.getTeamId())
                .eq(DirectoryEntity::getPid, param.getDirectoryId())).forEach(directory -> {
                    GetChildDirectoryListResult.ChildDirectory childDirectory = new GetChildDirectoryListResult.ChildDirectory();
                    BeanUtil.copyProperties(directory, childDirectory);
                    long count = this.count(new LambdaQueryWrapper<DirectoryEntity>().eq(DirectoryEntity::getPid, directory.getId()));
                    long docCount = docService.count(new LambdaQueryWrapper<DocEntity>().eq(DocEntity::getDirectoryId, directory.getId()));
                    childDirectory.setHasChild((count+docCount) > 0);
                    childDirectoryList.add(childDirectory);
        });
        docService.list(new LambdaQueryWrapper<DocEntity>()
                .eq(DocEntity::getProjectId, param.getProjectId())
                .eq(DocEntity::getTeamId, param.getTeamId())
                .eq(DocEntity::getDirectoryId, param.getDirectoryId()))
                .forEach(doc -> {
                    GetChildDirectoryListResult.ChildDocument childDocument = new GetChildDirectoryListResult.ChildDocument();
                    BeanUtil.copyProperties(doc, childDocument);
                    childDocumentList.add(childDocument);
                });
        result.setChildDirectoryList(childDirectoryList);
        result.setChildDocumentList(childDocumentList);
        return result;
    }

    @Override
    public void deleteDirectory(DeleteDirectoryParam param){
        if (ObjectUtil.isNotNull(param.getDirectoryId())) {
            // 获取 pids 包含当前目录 id 的所有记录
            List<DirectoryEntity> list = this.list(new LambdaQueryWrapper<DirectoryEntity>()
                    .like(DirectoryEntity::getPids,  param.getDirectoryId()));
            list.add(this.getById(param.getDirectoryId()));
            list.forEach(directory -> {
                // 删除文档
               docService.remove(new  LambdaQueryWrapper<DocEntity>().eq(DocEntity::getDirectoryId, directory.getId()));
            });
            this.removeBatchByIds(list);
        }
    }

    private DirectoryEntity setAreaPids(AddDirectoryParam param) {
        String userId = StpUtil.getLoginIdAsString();
        DirectoryEntity entity = new DirectoryEntity();
        entity.setName(param.getName());
        entity.setPid(param.getPid());
        if ("0".equals(param.getPid())) {
            entity.setPids("[0],");
        } else {
            DirectoryEntity pArea = getById(param.getPid());
            if (StrUtil.contains(pArea.getPids(), "["+param.getPid()+"]")) {
                throw new ServiceException(400, "父级区域不能放置在子区域中");
            }
            entity.setPid(param.getPid());
            entity.setPids(pArea.getPids()+"["+pArea.getId()+"],");
        }
        entity.setProjectId(param.getProjectId());
        entity.setTeamId(param.getTeamId());
        entity.setCreateUser(userId);
        return entity;
    }

}